﻿using System;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Windows.Forms;
using GetooLibs;
using Microsoft.Win32;
using System.Diagnostics;
using System.Deployment.Application;
using Schematrix;



namespace GTOFileMaker
{
    public partial class frmMain : Form
    {

        //environment const
        string UpdatePath;
        string UpdateUrl;
        DateTime LastCheckDate;
        int CheckInterval;

        //lpz
        string LpzPath = Properties.Settings.Default.LpzPath;

        //common
        WebClient client = new WebClient();
        GetooDatabaseFile currentDB = new GetooDatabaseFile();

        public frmMain()
        {
            InitializeComponent();
            bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted);
            AddShortcutToStartupGroup("Larvata", "Getoo");
        }

        #region FormBasicVisualibleControl

        private void ShowMainWindow()
        {
            if (this.ShowInTaskbar)
            {
                this.Show();
            }
            else
            {
                this.ShowInTaskbar = true;
                this.WindowState = FormWindowState.Normal;
            }
        }

        private void notify_DoubleClick(object sender, EventArgs e)
        {
            ShowMainWindow();
        }

        private void showWindowToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ShowMainWindow();
        }

        private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
        {

            if (e.CloseReason == CloseReason.UserClosing)
            {
                e.Cancel = true;
                this.Hide();
            }

        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        #endregion


        private void frmMain_Load(object sender, EventArgs e)
        {
            EnvironmentSetup();
            DoCheckUpdateWork(false);
            notify.Text = "Getoo";
            //btnCheckUpdate.Enabled = true;
            if (LpzExecute())
            {
               // notify.ShowBalloonTip(5, "Lpz1.01", "LpzExecute() fin.", ToolTipIcon.Info);
            }
            else
            {
               // notify.ShowBalloonTip(5, "Lpz1.01", "LpzExecute() err.", ToolTipIcon.Info);
            }
            //LpzExecute();
        }

        private void DoCheckUpdateWork(bool isForce)
        {
            if (isForce || IsNeedsCheck())
            {

                if (!bgWorker.IsBusy)
                {
                    //notify.ShowBalloonTip(5, "bgWorker", "start work.", ToolTipIcon.Info);
                    btnCheckUpdate.Enabled = false;
                    bgWorker.RunWorkerAsync();
                }
            }
        }

        /// <summary>
        /// Check if should be check update 
        /// </summary>
        /// <returns></returns>
        private bool IsNeedsCheck()
        {
            DateTime lastDate = Properties.Settings.Default.LastCheckUpdate;
            int timeCheckInterval = Properties.Settings.Default.CheckInterval;

            if (DateTime.Now.Subtract(lastDate).TotalHours > timeCheckInterval)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// Check weather local db matchs server db
        /// </summary>
        /// <returns></returns>
        private bool CheckUpdateAvailable()
        {
            try
            {
                client.DownloadFile(
                    UpdateUrl + "/getoo.db",
                    UpdatePath + "/getoo.db");
            }
            catch (WebException)
            {


            }



            currentDB = Utility.LoadGetooDatabaseFile(UpdatePath + @"\getoo.db");

            if (Properties.Settings.Default.UpdateVersion < currentDB.Version)
            {
                return true;
            }
            else
            {
                return false;
            }


        }

        /// <summary>
        /// Get  files in getoo.db from SERVER 
        /// skip existed files
        /// </summary>
        /// <returns>
        /// if success returns count of files downloaded
        /// if download error returns -1
        /// </returns>
        private int GetUpdateFiles()
        {
            int fileUpdatedCount = 0;
            bool errorOccured = false;

            string fileUrl, filePath;


            foreach (GetooFile file in currentDB.Files)
            {
                
                fileUrl = UpdateUrl +"/"+ file.TargetApplication+"/" +file.Hash;
                filePath = UpdatePath + file.TargetApplication + file.FileName;

                //check if file existed
                if (File.Exists(filePath))
                {
                    if (file.Hash == Utility.GetFileHash(filePath))
                    {
                        continue;
                    }

                }

                //file not exist or needs to update
                if (!Directory.Exists(UpdatePath + file.TargetApplication))
                {
                    //MessageBox.Show(UpdatePath + file.TargetApplication);
                    Directory.CreateDirectory(UpdatePath + file.TargetApplication);
                }

                try
                {
                    client.DownloadFile(fileUrl, filePath);

                    File.SetLastWriteTime(filePath, file.ModifyDate);
                    //Unrar unrar = new Unrar();
                    //unrar.ExtractAllFilesToDirectory(filePath, UpdatePath + file.TargetApplication);
                    //unrar.Close();
                    //File.Delete(filePath);
                    fileUpdatedCount++;

                }
                catch ( Exception  )
                {
                    //MessageBox.Show(ex.Message +"\r\n"+filePath);
                    //MessageBox.Show(ex.Message);
                    errorOccured = true;
                    //throw;
                }

            }

            if (!errorOccured)
            {
                Properties.Settings.Default.LastCheckUpdate = DateTime.Now;
                Properties.Settings.Default.UpdateVersion = currentDB.Version;
                Properties.Settings.Default.Save();
                return fileUpdatedCount;
            }
            else
            {
                return -1;
            }


        }

        private void bgWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            int filesUpdated = 0;
            if (CheckUpdateAvailable())
            {
                filesUpdated = GetUpdateFiles();

                //MessageBox.Show("updated " +.ToString());

            }

            if (filesUpdated == -1)
            {
                notify.ShowBalloonTip(10, "Download Error!", "New updates available \r\nbut failed to download update files", ToolTipIcon.Info);

            }
            else
            {


                if (filesUpdated > 0)
                {
                    notify.ShowBalloonTip(10, "Download Succeed!", "Download " + filesUpdated.ToString() + "file(s)\r\n" + UpdatePath, ToolTipIcon.Info);

                }

                Properties.Settings.Default.LastCheckUpdate = DateTime.Now;
                Properties.Settings.Default.Save();
                EnvironmentSetup();
            }



        }

        private void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            btnCheckUpdate.Enabled = true;
        }

        private void EnvironmentSetup()
        {
            //社保程序主目录
            UpdatePath =@"D:\Sbk\Software\"; 
            UpdateUrl = Properties.Settings.Default.ServerIP;
            LastCheckDate = Properties.Settings.Default.LastCheckUpdate;
            CheckInterval = Properties.Settings.Default.CheckInterval;

            txtServerIP.Text = UpdateUrl;
            txtCheckInterval.Text = CheckInterval.ToString();

            labLastCheckedDate.Text = LastCheckDate.ToString();
            //btnServerStatus set in checkupdateavailable
            btnNextCheckDate.Text = LastCheckDate.AddHours(CheckInterval).ToString();
            //myip no code
            labVersion.Text = "Version: " +System.Deployment.Application.ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();


            if (!Directory.Exists(UpdatePath))
            {
                Directory.CreateDirectory(UpdatePath);
            }


            //check server
            try
            {
                client.DownloadData(UpdateUrl + "/getoo.db");
                btnServerStatus.ForeColor = System.Drawing.Color.DarkGreen;
                btnServerStatus.Text = "Success";
            }
            catch (Exception)
            {
                btnServerStatus.ForeColor = System.Drawing.Color.Red;
                btnServerStatus.Text = "Connect Failed";
                //throw;
            }


        }

        private void btnServerStatus_Click(object sender, EventArgs e)
        {
            txtServerIP.Visible = true;


        }

        private void txtServerIP_DoubleClick(object sender, EventArgs e)
        {
            txtServerIP.Visible = false;
            Properties.Settings.Default.ServerIP = txtServerIP.Text;
            Properties.Settings.Default.Save();
            EnvironmentSetup();

        }

        private void btnNextCheckDate_Click(object sender, EventArgs e)
        {
            txtCheckInterval.Visible = true;
        }

        private void txtCheckInterval_DoubleClick(object sender, EventArgs e)
        {
            txtCheckInterval.Visible = false;
            Properties.Settings.Default.CheckInterval = int.Parse(txtCheckInterval.Text);
            Properties.Settings.Default.Save();
            EnvironmentSetup();
        }

        private void btnCheckUpdate_Click(object sender, EventArgs e)
        {
            DoCheckUpdateWork(true);
        }




        /// <summary>
        /// 冷僻字检查文件齐全 更新到系统目录 注册输入法 启动冷僻字
        /// </summary>
        /// <returns></returns>
        private bool LpzExecute() 
        {
            //冷僻字安装目录
            string LpzPath=UpdatePath+@"\LPZ1.01";

            txtLpzPath.Text = LpzPath;
            /*
                *冷僻字程序更新逻辑（在注册表中未对码表、字体主动设置路径的情况下）
                * 1.复制update文件夹的文件到目标位置
                * 2.lpzmz.ttf 复制到冷僻字安装目录下
                * 3.lpz.ctb 复制到冷僻字安装目录下
                * 4.jwz.mb sjm.mb 复制到%system32%下
            */

            //检查所需文件是否存在
            if (!(File.Exists(LpzPath + @"\jwz.ime")&&
                File.Exists(LpzPath + @"\jwz.mb")&&
                File.Exists(LpzPath + @"\sjm.ime")&&
                File.Exists(LpzPath + @"\sjm.mb")&&
                File.Exists(LpzPath + @"\lpzme.ttf")))
            {
                return false;
            }

            //所需文件存在 检查是否需要更新到系统中
            try
            {
                //检查%system32%下的jwz.ime jwz.mb sjm.ime sjm.mb 是否和程序目录中一致，一致则认为文件为最新
                if (Utility.GetFileHash(Environment.SystemDirectory + @"\jwz.ime") != Utility.GetFileHash(LpzPath + @"\jwz.ime"))
                    File.Copy(LpzPath + @"\jwz.ime", Environment.SystemDirectory + @"\jwz.ime", true);

                if (Utility.GetFileHash(Environment.SystemDirectory + @"\jwz.mb") != Utility.GetFileHash(LpzPath + @"\jwz.mb"))
                    File.Copy(LpzPath + @"\jwz.mb", Environment.SystemDirectory + @"\jwz.mb", true);

                if (Utility.GetFileHash(Environment.SystemDirectory + @"\sjm.ime") != Utility.GetFileHash(LpzPath + @"\sjm.ime"))
                    File.Copy(LpzPath + @"\sjm.ime", Environment.SystemDirectory + @"\sjm.ime", true);

                if (Utility.GetFileHash(Environment.SystemDirectory + @"\sjm.mb") != Utility.GetFileHash(LpzPath + @"\sjm.mb"))
                    File.Copy(LpzPath + @"\sjm.mb", Environment.SystemDirectory + @"\sjm.mb", true);

                /*
                 * lpzme.ttf 不用检查system32下的那个 根本不用那个 todo: delete
                if (Utility.GetFileHash(Environment.SystemDirectory + @"\lpzME.ttf") != Utility.GetFileHash(LpzPath + @"\lpzME.ttf"))
                {
                    File.Copy(LpzPath + @"\lpzME.ttf", Environment.SystemDirectory + @"\lpzME.ttf", true);
                }
                */

            }
            catch (Exception ex)
            {
                notify.ShowBalloonTip(5000, "LpzExecute()", ex.Message, ToolTipIcon.Info);
            }


            //注册输入法 始终
            Process.Start(LpzPath + @"\imetool.exe", "/install:jwz.ime /install:sjm.ime");         

            //启动冷僻字
            try
            {
                Process.Start(LpzPath + @"\lpz.exe");
            }
            catch (Exception)
            {
                return false;
            }

            DateTime currentDate = File.GetLastWriteTime(LpzPath + @"\LpzME.ttf");
            if (currentDate.Year < 1900)
            {
                labLpzVersion.Text = "Not found LpzME.ttf";
            }
            else
            {
                labLpzVersion.Text = currentDate.ToShortDateString();
            }

            return true;
        }




        private void AddShortcutToStartupGroup(string publisherName, string productName)
        {
            if (ApplicationDeployment.IsNetworkDeployed &&

            ApplicationDeployment.CurrentDeployment.IsFirstRun)
            {

                string startupPath = Environment.GetFolderPath(Environment.SpecialFolder.Startup);

                startupPath = Path.Combine(startupPath, productName) + ".appref-ms";

                if (!File.Exists(startupPath))
                {

                    string allProgramsPath = Environment.GetFolderPath(Environment.SpecialFolder.Programs);

                    string shortcutPath = Path.Combine(allProgramsPath, publisherName);

                    shortcutPath = Path.Combine(shortcutPath, productName) + ".appref-ms";

                    File.Copy(shortcutPath, startupPath);

                }

            }

        }





        private bool LpzCheckStartup()
        {
            string lpzPath = string.Empty; ;
            try
            {
                lpzPath = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true).GetValue("LPZ1.01").ToString();

            }
            catch (Exception)
            {


            }
            if (string.IsNullOrEmpty(lpzPath))
            {
                return false;
            }
            else
            {
                return true;
            }

        }


        private void button1_Click(object sender, EventArgs e)
        {
            LpzExecute();
        }
    }
}
